複数システムで1つのRDSインスタンスを共用する。について考えてみた
3つのシステムを作ろう。基本的な構成は同じ。可用性を高めるためにマルチAZ構成とする。
よし、あとはコストを算出だ。あれっ、ランニングコストが想定よりも高いな。。どうしよう。。
そんな場面によく遭遇します。
コスト削減で考えられるポイントとしては、
- インスタンスタイプを見直す
- マルチAZからシングルAZに変更する
- 複数システムを1つのVPCに同居させALBを共用する
- 複数システムでRDSインスタンスを共用する
などいくつかあると思いますが、今回は複数システムでRDSインスタンスを共用するについて考えてみます。対象システムの想定は以下の通り。
- システムとしての重要度、ライフサイクル(寿命)が同じくらい
- 極端な負荷が発生する見込みがない小規模なもの
※コスト的に問題なければ、多くの場合全てのリソースを分離した方が良いです(何も共用しない)
複数システムでRDSインスタンスを共用することによるメリット
コストの削減が唯一にして最大のメリットです。
2019/10月現在、東京リージョンでMySQLのdb.m5.large
インスタンスをマルチAZで利用する場合、0.47USD/hのコストが発生します。一月を31日で計算した場合、おおよそ350USD/mon、日本円にして37,800円/月になります。
もちろんインスタンスタイプをT系に変更することでコスト削減をすることも可能ですが、よく検討しないと思ったよりパフォーマンスが出ないといった状況に陥ります。※RDSへの負荷を十分検討した上でT3系のインスタンスタイプを利用する選択肢はありだと思います。
3つのシステムで無難にdb.m5.large
インスタンスを利用する方針にした場合(マルチAZ)、それだけで113,400円/月のコストが発生してしまいます。
仮に3つのシステムを1つのRDSインスタンスに集約できれば、RDSにかかる料金は37,800円/月で済みます。
複数システムでRDSインスタンスを共用することによるデメリット
いくつか挙げられますが、特に気になるところとしてはこの辺り
- インスタンスとしての設定値が全てのシステムで共通になる
- RDSの機能としてのバックアップがインスタンス単位になる
- RDSインスタンスのリソースを全てのシステム共用する
- アクセス制御が難しい
- PerformanceInsightにおいて、全てのシステムのクエリが混ざる
詳細は以下にまとめますが対象となるシステムを複数のベンダーで開発する場合デメリットを払拭するのはなかなか難しいような気がします。
インスタンスとしての設定値が全てのシステムで共通になる
RDSインスタンス作成時に指定する設定値は全てのシステムで共通になります。
- DBエンジンのバージョン
- バックアップ期間
- メンテナンスウィンドウの時間(パッチ適用等が行われる時間)
- など
Aシステムでは5.7系を利用したい、Bシステムでは8.0系を使いたい、は当然できませんし、バックアップの保持期間、パッチ適用のタイミングなども全システム共通になります。
RDSの機能としてのバックアップがインスタンス単位になる
RDSの機能として取得できるバックアップはインスタンス単位です。そのため、AシステムのDBのみ昨日のバージョンに戻すのようなことはできません。それをしたい場合は、DB単位でバックアップをする。もしくは、RDSの機能として取得したバックアップをリストアし、リストアされたインスタンスからDB単位でバックアップを取得し、既存インスタンスにリストアする必要があります。
RDSインスタンスのリソースを全てのシステム共用する
これは当然なのですが全てのシステムでリソースを共用します。そのため、Aシステムがコストの高いクエリを実行した場合、他システムはその影響を受けます。不特定多数に利用されるシステムの場合、その他システムに影響を与える可能性も高くなります。
アクセス制御が難しい
AシステムのEC2はAシステムのDBにしか接続できないをAWSの機能として実現することはできません。データベース側の機能として実現する必要があります。(AシステムにはAシステムのDBしかさわれないユーザーを作成するなど適切な権限を配布する必要があります)
PerformanceInsightにおいて全てのシステムのクエリが混ざる
PerformanceInsightはとても便利な機能です。この仕組みを利用することでデータベースのボトルネックを検出することができます。複数システムで共用する場合は全てのクエリが混ざった状態で表示されます。
デメリットを受け入れた上で設計するときのポイント
デメリット全て受け入れてでもコスト削減したいケースもあるかもしれません。その際の設計ポイントは以下になります。
- 各システムでVPCを分ける
- RDS接続のエンドポイントはプライベートHostedZoneで管理する
※場合によっては、共用RDSだけのVPCを作成しても良いかもしれません。
各システムでVPCを分ける
1つのシステムが大きく育つかもしれません。そのためVPC PeeringでRDSに接続します。将来的に自分のシステムだけのRDSを作成する場合は、自システムのVPCにRDSインスタンスを作成します。 Peeringによるコストも発生しますが、将来的なことを考えると分けておいたほうが良いと思います。
プライベートHostedZone等でCNAME管理
プライベートHostedZoneを利用しエンドポイントを解決します。将来的に別RDSを利用することになった際のアプリケーション変更箇所を最小限にします。
まとめ
AWS利用費におけるRDS利用費の割合は高くなることが多く、コスト削減対象のリソースになりがちです。ただ複数システムのデータストアを1つのRDSインスタンスに集約するのはリスクも伴います。集約する場合は、デメリット、および将来的なことも考慮した上で構築することをお勧めいたします。